<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\api\controller\v1;

use app\api\controller\Basic;
use app\common\model\UserAddress;
use app\common\model\User as AppUser;
use buwang\facade\SmsFacade;
use app\common\model\Sms;
use upload\Uploadfile;
use app\manage\model\City;
use app\common\model\UserRecharge;
use buwang\util\Caches;
use app\common\model\system\SysCity as CityModel;
use app\common\model\system\SysRegion;
use app\common\model\UserBill;

class User extends Basic
{
    protected function initialize()
    {
        parent::initialize();
        $this->isUserAuth();
    }

    /**
     * 删除地址
     */
    public function delAddress()
    {
        $uid = $this->uid;
        $id = request()->param('id/d', 0);
        if (!$id || !is_numeric($id)) return $this->error('参数错误!');
        if (!UserAddress::where(['is_del' => 0, 'id' => $id, 'user_id' => $uid])->find())
            return $this->error('地址不存在!');
        if (UserAddress::where('id', $id)->update(['is_del' => '1']))
            return $this->success('删除成功');
        else
            return $this->error('删除地址失败!');
    }


    /**
     * 设置地址为默认
     */
    public function setDefault()
    {
        $uid = $this->uid;
        $id = request()->param('id/d', 0);
        if (!$id || !is_numeric($id)) return $this->error('参数错误!');
        if (!UserAddress::where(['is_del' => 0, 'id' => $id, 'user_id' => $uid])->find()) return $this->error('地址不存在!');
        UserAddress::where('id', $id)->update(['is_default' => 1]);
        //如果设置了默认地址则更新其他地址为非默认
        UserAddress::where(['user_id' => $uid])->where('id', '<>', $id)->update(['is_default' => 0]);
        return $this->success('设置成功');
    }

    /**
     * 地址列表
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getAddressList()
    {
        $uid = $this->uid;
        $page = request()->get('page/d', 0);
        $limit = request()->get('limit/d', 20);
        $list = UserAddress::getUserValidAddressList($uid, $page, $limit, 'id,real_name,mobile,province,city,district,detail,is_default');
        return $this->success('查询成功', $list);
    }

    /**
     * 获取默认地址
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getDefaultAddress()
    {
        $param['key'] = $this->request->param('key/d');
        $param['sign'] = $this->request->param('sign');
        $rel = $this->apiSignCheck($param);
        if ($rel['code'] != 200) {
            return $this->code(200)->error('签名失败');
        }
        if ($param['key']) {
            $result = UserAddress::where(['user_id' => $this->user->id, 'id' => $param['key']])->find();
        } else {
            $result = UserAddress::where(['user_id' => $this->user->id, 'is_default' => 1])->find();
        }

        if (empty($result)) {
            return $this->success('没有内容了');
        } else {
            return $this->success('获取成功', $result);
        }
    }

    /**
     * 保存或修改我的地址
     */
    public function addAddress()
    {
        if (request()->isPost()) {
            $param = [
                'id' => $this->request->param('id/d'),
                'real_name' => $this->request->param('real_name/s'),
                'mobile' => $this->request->param('mobile/s'),
                'province' => $this->request->param('province/s'),
                'city' => $this->request->param('city/s'),
                'district' => $this->request->param('district/s'),
                'detail' => $this->request->param('detail/s'),
                'city_id' => $this->request->param('city_id/s'),
                'post_code' => $this->request->param('post_code/s'),
                'is_default' => $this->request->param('is_default/d', 0),//是否默认
                'sign' => $this->request->param('sign/s'),
            ];

            //下面的验证失败，全局会捕获
            validate(\buwang\validate\Address::class)->scene('add')->check($param);

            if (!empty($param['sign'])) {
                $rel = $this->apiSignCheck($param);
                if ($rel['code'] != 200) {
                    return $this->code(200)->error('签名失败');
                }
            }
            //传id更新指定地址
            if ($param['id']) {
                $userAddress = UserAddress::where(['user_id' => $this->user->id])->where('id', $param['id'])->find();
                if (!$userAddress) return $this->code(200)->error('差找不到该地址');
                //不传id更新默认地址或新增地址
            } else {
                //否则新增
                $userAddress = new UserAddress;
            }
            //把所有地址重置非默认
            $data['real_name'] = $param['real_name'];
            $data['mobile'] = $param['mobile'];
            $data['is_default'] = $param['is_default'];
            $data['province'] = $param['province'];
            $data['city'] = $param['city'];
            $data['district'] = $param['district'];
            $data['detail'] = $param['detail'];
            $data['city_id'] = $param['city_id'];
            $data['post_code'] = $param['post_code'];
            $data['user_id'] = $this->user->id;
            $data['member_miniapp_id'] = $this->app_id;
            $data['create_time'] = time();
            $data['update_time'] = time();
            if ($data['city_id']) {
                $data['city_code'] = City::where('area_code', 'like', "{$data['city_id']}%")->value('city_id'); //城市表city_id
            }
            $result = $userAddress->save($data);
            if ($result) {
                //如果设置了默认地址则更新其他地址为非默认
                if ($param['is_default'] == 1) UserAddress::where(['user_id' => $this->user->id])->where('id', '<>', $userAddress->id)->update(['is_default' => 0]);
                return $this->code(200)->success('成功', $userAddress);
            } else {
                return $this->code(200)->error('失败');
            }
        } else {
            return $this->code(200)->error('非法请求');
        }
    }

    /**
     * 绑定手机号(h5)
     * bindWechatMobile
     * @return \think\Response
     */
    public function bindPhoneNumber()
    {
        if (request()->isPost()) {

            $data = [
                'phone' => $this->request->param('phone/s'),
                'code' => $this->request->param('code/d'),
            ];
//            $validate = $this->validate($data, 'User.bindphone');
//            if (true !== $validate) {
//                return  $this->code(200)->error($validate, [], 204);
//            }

             $mobile = $data['phone'];
                    if ($this->user->mobile == $mobile) {
                        return $this->code(200)->error('手机号相同不用更换', [], 204);
                    }
                    $rel = AppUser::where(['member_miniapp_id' => $this->app_id, 'mobile' => $mobile])->field('id')->count();
                    if ($rel) {
                        return $this->code(200)->error('手机号已被占用', [], 204);
                    }
            //判断安全密码是否正确 session中
            if(!Sms::check($mobile, $data['code'], 'change_phone'))return $this->code(200)->error('验证码错误');
                    //验证通过
                    $res = AppUser::where(['id' => $this->user->id])->update(['mobile' => $mobile]);
                    if ($res) {
                        Sms::clear($this->user->mobile,'change_phone');
                        return $this->code(200)->success('手机号绑定成功', ['mobile' => $mobile]);
                    }
                    return $this->code(200)->error('手机号绑定失败', [], 204);
        } else {
            return $this->code(200)->error('非法请求');
        }
    }


    /**
     * 获取绑定手机号验证码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getPhoneCode()
    {
        if (request()->isPost()) {
            $data = [
                'phone' => Request::param('phone/s'),
                'types' => Request::param('types/d'),
            ];
            $validate = $this->validate($data, 'User.getphone');
            if (true !== $validate) {
                return json(['code' => 403, 'msg' => $validate]);
            }
            if ($data['types']) { //验证自己手机号
                if ($this->user->phone_uid != $data['phone']) {
                    return json(['code' => 403, 'msg' => '不是您绑定的手机号']);
                }
            } else {
                //新绑定
                $rel = AppUser::where(['member_miniapp_id' => $this->miniapp_id, 'phone_uid' => $data['phone']])->field('phone_uid')->find();
                if (!empty($rel)) {
                    return json(['code' => 403, 'msg' => '手机号已绑定']);
                }
            }
            $rel = Alisms::putSms($data['phone'], $this->miniapp->member_id);
            if ($rel['code'] == 200) {
                return json(['code' => 200, 'msg' => $rel['message'], 'data' => session_id()]);
            } else {
                return json(['code' => 403, 'msg' => $rel['message']]);
            }
        }
    }

    /**
     * 获取已绑定手机号验证码
     * @param int $user_id 用户ID
     * @param string $safepassword 验证的安全密码
     * @return \think\response\Json
     */
    public function getUserPhoneCode(int $user_id, string $safepassword)
    {
        if (empty($this->user->phone_uid)) {
            return json(['code' => 403, 'msg' => '你没有绑定手机号']);
        }
        $rel = Alisms::putSms($this->user->phone_uid, $this->miniapp->member_id);
        if ($rel['code'] == 200) {
            return json(['code' => 200, 'msg' => $rel['message'], 'data' => session_id()]);
        } else {
            return json(['code' => 403, 'msg' => $rel['message']]);
        }
    }


    /**
     * 获取已绑定手机号验证码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getFriendPhoneCode()
    {
        if (request()->isPost()) {
            $data['phone'] = Request::param('phone/s');
            $validate = $this->validate($data, 'User.getphone');
            if (true !== $validate) {
                return json(['code' => 403, 'msg' => $validate]);
            }
            if ($this->user->phone_uid == $data['phone']) {
                return json(['code' => 403, 'msg' => '非好友手机号']);
            }
            //查找所属用户
            $user = AppUser::field('phone_uid')->where(['member_miniapp_id' => $this->miniapp_id, 'phone_uid' => $data['phone']])->find();
            if (empty($user)) {
                return json(['code' => 403, 'msg' => '未找到当前用户']);
            }
            $rel = Alisms::putSms($user->phone_uid, $this->miniapp->member_id);
            if ($rel['code'] == 200) {
                return json(['code' => 200, 'msg' => $rel['message'], 'data' => session_id()]);
            } else {
                return json(['code' => 403, 'msg' => $rel['message']]);
            }
        }
    }

    /**
     * 验证是否绑定手机号
     * @return \think\response\Json
     */
    public function isBandMobile()
    {
        if (empty($this->user->mobile)) {
            return json(['code' => 204, 'msg' => '未绑手机号']);
        }
        return json(['code' => 200, 'msg' => '已绑定手机号']);
    }

    /**
     * 验证是否设置安全密码
     * @param int $type
     */
    public function isSafePassword(int $type = 0)
    {
        // var_dump($this->user);die;
        $type = $this->request->param('type/d', 0);
        if ($type) {
            if (!$this->user->mobile) {
                return $this->code(200)->error('请先绑定手机号', ['url' => '/pages/common/bindphone']);
            }
        }
        if ($this->user->safe_password) {
            return $this->success('已设置安全密码');
        } else {
            return $this->success('未设置安全密码', [], 204);
        }
    }

    /**
     * 检查旧的安全密码
     */
    public function checkSafePassword()
    {
        if (request()->isPost()) {
            $data = [
                'safe_password' => $this->request->param('safe_password/s'),
            ];
            //下面的验证失败，全局会捕获
            validate(\buwang\validate\User::class)->scene('safePassword')->check($data);
            //TODO：验证安全密码
            if (password_verify(md5($data['safe_password']), $this->user->safe_password)) {
                return $this->success('安全密码验证通过');
            } else {
                return $this->code(200)->error('安全密码不正确');
            }
        }
    }

    /**
     * 设置安全密码6位数字
     *
     * @return void
     */
    public function setSafePassword()
    {
        if (request()->isPost()) {
            $data = [
                'safe_password' => $this->request->param('safe_password/s'),
                'password_confirm' => $this->request->param('resafe_password/s'),
                'code' => $this->request->param('code/d'), //短信验证码
            ];
            //下面的验证失败，全局会捕获
            validate(\buwang\validate\User::class)->scene('setSafePassword')->check($data);

            //判断安全密码是否正确 session中
            $check_sms = SmsFacade::checkSms($this->user->mobile, $data['code']);
            if (!$check_sms) {
                return $this->code(200)->error('验证码错误');
            }
            $result = AppUser::updateSafePasspord($this->user->id, $data['safe_password']);
            if ($result) {
                return $this->success('操作成功');
            } else {
                return $this->code(200)->error('操作失败');
            }
        }
    }


    /**
     * 设置安全密码6位数字(H5)
     *
     * @return void
     */
    public function setSafePasswordH5()
    {
        if (request()->isPost()) {
            $data = [
                'safe_password' => $this->request->param('safe_password/s'),
                'password_confirm' => $this->request->param('resafe_password/s'),
                'code' => $this->request->param('code/d'), //短信验证码
            ];
            //下面的验证失败，全局会捕获
//            validate(\buwang\validate\User::class)->scene('setSafePassword')->check($data);

            //判断安全密码是否正确 session中
            if(!Sms::check($this->user->mobile, $data['code'], 'safe_password'))return $this->error('验证码错误');
            $result = AppUser::updateSafePasspord($this->user->id, $data['safe_password']);
            if ($result) {
                Sms::clear($this->user->mobile,'safe_password');
                return $this->success('操作成功');
            } else {
                return $this->error('验证码错误');
            }
        }
    }


    /**
     * 读取我的推荐用户(只显示两层关系)
     * @return \think\response\Json
     */
    public function levelUser()
    {
        $info = UserLevel::levelUser($this->user->id, 1);
        if ($info) {
            return json(['code' => 200, 'msg' => '成功', 'data' => $info]);
        }
        return json(['code' => 204, 'msg' => '空内容']);
    }

    /**
     * 上传接口
     * @return \think\Response
     */
    public function upload()
    {
        $data = [
            'upload_type' => $this->request->post('upload_type'),
            'file' => $this->request->file('file'),
        ];
        $uploadConfig = bw_config('base');
        $uploadConfig['upload_allow_type'] = "local,alioss,qnoss,txcos";
        empty($data['upload_type']) && $data['upload_type'] = $uploadConfig['upload_type'];
        if ($data['upload_type'] !== 'local') {
            $uploadConfig = array_merge($uploadConfig, bw_config($data['upload_type']));
        }
        $rule = [
            'upload_type|指定上传类型有误' => "in:{$uploadConfig['upload_allow_type']}",
            'file|文件' => "require|file|fileExt:{$uploadConfig['upload_allow_ext']}|fileSize:{$uploadConfig['upload_allow_size']}",
        ];
        $this->validate($data, $rule);
        try {
            $upload = Uploadfile::instance()
                ->setUploadType($data['upload_type'])
                ->setUploadConfig($uploadConfig)
                ->setFile($data['file'])
                ->save();
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
        if ($upload['save'] == true) {
            return $this->success($upload['msg'], ['src' => $upload['url']]);
        } else {
            return $this->error($upload['msg']);
        }
    }


    /**
     * 充值套餐选择
     */
    public function moneySelect()
    {
        $recharge_select = bw_data('recharge_select');
        if (!$recharge_select) return $this->error('未设置充值套餐，请联系客服');
        return $this->success('查询成功', ['data' => $recharge_select, 'desc' => bw_config('recharge_info', '')]);
    }


    /**
     * 充值余额
     */
    public function rechargeMoney()
    {
        $selectId = $this->request->param('select_id/d', 0);//充值套餐id
        $price = $this->request->param('price/f', 0);//充值金额
        $type = $this->request->param('type/s'); //支付方式
        $res = UserRecharge::createRecharge($this->user->id, $selectId, $price, $type, $this->bwapp->id, true);
        if (!$res) return $this->error(UserRecharge::getError());
        return $this->success('下单成功', $res);
    }

    /**
     * 充值记录
     */
    public function rechargeList()
    {
        $user = $this->user;//登录用户
        if (request()->isGet()) {
            $page = $this->request->get('page/d');
            $limit = $this->request->get('limit/d');
            $list = UserRecharge::rechargeList($user['id'], $page, $limit);
            return $this->success('查询成功', $list);
        }
    }

    /**
     * 查找城市数据
     */
    public function cityList()
    {
        $list = Caches::get('CITY_LIST', function () {
            $list = CityModel::with('children')->field(['city_id', 'name', 'area_code', 'id', 'parent_id'])->where('parent_id', 0)->order('id asc')->select()->toArray();
            $data = [];
            foreach ($list as &$item) {
                $item['area_code'] = CityModel::getCode($item['area_code']);
                $value = ['v' => $item['city_id'], 'a' => $item['area_code'], 'n' => $item['name']];
                if ($item['children']) {
                    foreach ($item['children'] as $key => &$child) {
                        $child['area_code'] = CityModel::getCode($child['area_code']);
                        $value['c'][$key] = ['v' => $child['city_id'], 'a' => $child['area_code'], 'n' => $child['name']];
                        unset($child['id'], $child['area_code'], $child['merger_name'], $child['is_show'], $child['level'], $child['lng'], $child['lat'], $child['lat']);
                        if (CityModel::where('parent_id', $child['city_id'])->count()) {
                            $child['children'] = CityModel::where('parent_id', $child['city_id'])->field(['city_id', 'area_code', 'name', 'id', 'parent_id'])->select()->toArray();
                            foreach ($child['children'] as $kk => $vv) {
                                $vv['area_code'] = CityModel::getCode($vv['area_code']);
                                $value['c'][$key]['c'][$kk] = ['v' => $vv['city_id'], 'a' => $vv['area_code'], 'n' => $vv['name']];
                            }
                        }
                    }
                }
                $data[] = $value;
            }

            return $data;
        }, 0);
        return $this->success('获取成功', $list);
    }

    /**
     * 查找城市数据类型2
     */
    public function cityListTwo()
    {
        $list = Caches::get('CITY_LIST_TWO', function () {
            return SysRegion::getList();
        }, 0);
        return $this->success('获取成功', $list);
    }

    /**
     * 账单
     * @param $type 0 全部  1 消费  2 转换 3 返佣
     * @return mixed
     */
    public function billList($type)
    {
        $page = request()->get('page/d', 1);
        $limit = request()->get('limit/d', 20);
        //$category brokerage 佣金  money 余额  integral 积分  微信 weixin
        $category = request()->get('category/s', '');
        if ($category) {
            foreach (explode(',', $category) as $value) {
                if (!in_array($value, ['brokerage', 'money', 'integral', 'weixin'])) return $this->error('参数非法');
            }
        }
        $uid = $this->uid;
        return $this->success('查询成功', UserBill::getUserBillList($uid, $page, $limit, $type, $category));
    }

    /**
     * 根据推广码获取个人信息
     * @return mixed
     */
    public function getCodeUser()
    {
        return self::getInviteCodeUser();
    }

    /**
     * 忘记密码
     * @return \think\Response
     */
    public function setPassword()
    {
        if (request()->isPost()) {
            $data = [
                'mobile' => $this->request->param('mobile/s',''),
                'password' => $this->request->param('password/s',''),
                'password_two' => $this->request->param('re_password/s',''),
                'code' => $this->request->param('code/d'), //短信验证码
            ];
            validate(\buwang\validate\User::class)->scene('setPassword')->check($data);
            $user = AppUser::where('member_miniapp_id', $this->app_id)->where('mobile',$data['mobile'])->find();
            if(!$user) return $this->code(200)->error('手机号未注册或为被绑定');
            //判断安全密码是否正确 session中
            if(!Sms::check($user->mobile, $data['code'], 'password')) return $this->code(200)->error('验证码错误');
            $result =(new AppUser)->upLoginPasspowrd($user->id, $data['password']);
            if ($result) {
                Sms::clear($user->mobile,'password');
                return $this->code(200)->success('操作成功');
            } else {
                return $this->code(200)->error('验证码错误');
            }
        }
    }



}